package workforecast

import org.springframework.dao.DataIntegrityViolationException

class ReportController {

    static allowedMethods = [save: "POST", update: "POST", delete: "POST"]

    def index() {

		redirect(action:"list", params:params)
    }
	
	def int calculateARVE(int timeOnEngagementOverrunsIncluded, int totalPaidTime, int totalPaidTimeOnVacation) {
		
		
		def result = timeOnEngagementOverrunsIncluded / (totalPaidTime-totalPaidTimeOnVacation)
		return result;
	} 
	
	def int calculateURVE(int timeOnEngagementOverrunsExcluded, int totalPaidTime, int totalPaidTimeOnVacation) {
		
		
		def result = timeOnEngagementOverrunsExcluded / (totalPaidTime-totalPaidTimeOnVacation+1)
		return result;
	}
	
	def reportMenu() {
		
	}
	
	def report(long id) {
		
		
		
		def timeOnEngagementOverrunsIncluded = 0;
		def timeOnEngagementOverrunsExcluded = 0;
		def totalPaidTime = 0
		def totalPaidTimeOnVacation = 0;
		
		Report report = Report.get(id)
		User consultant = User.findByUsername(report.consultant)
		
		if (consultant.role.name.equals("Manager"))  {
			
		}
		
		
		// Date format: YYYYWW
		int startDate = report.startYear * 100 + report.startWeek
		int endDate = report.endYear * 100 + report.endWeek
		
		
		
		
		


		
		System.out.println("BBBBBBBBBBB " + session.getAttribute("me"))
		def List<Integer> weekInterval = new ArrayList<Integer>();
		Forecast[] availableForecastsForConsultant = consultant.forecasts
		def workloadsForReportWeeks = new ArrayList()

		def i = startDate
		while (i <= endDate) {
			String week = (int) (i - (Math.floor(i / 100) * 100))
			String year = (int)  Math.floor(i / 100)
			String label = week + "/" + year
			weekInterval.add(label)
			i++;
		} 
		
		def selectedForecastsArray = new ArrayList() // forecast for the right weeks
		
		for (int c=0; c < availableForecastsForConsultant.length; c++) {
			def forecast = availableForecastsForConsultant[c]
			
			int forecastStartDate = forecast.startYear * 100 + forecast.startWeek
			int forecastEndDate = forecast.endYear * 100 + forecast.endWeek
			
			for (int date = forecastStartDate; date <= forecastEndDate; date++) {
				if ((date <= endDate) && (date >= startDate)) {
					selectedForecastsArray.add(forecast)
					break
				}
			}
		}
		
		int workloadForEngagements = 0 
		int workloadForBillable = 0
		int workloadForPaidVacation = 0
		int workloadForPaid = 0
		int availabilityPaid = 0
		
		for (int z = 0; z < selectedForecastsArray.size(); z++) {
			def forecast = selectedForecastsArray.get(z)
			
			def complecompleteWorkload = forecast.activities*.workloadEstimation.sum()
			def availability = 100 - complecompleteWorkload
			
			if (availability >= 0) {
				availabilityPaid += availability
			}

			
			Activity[] activitiesForForecast = selectedForecastsArray[z].activities.toArray()
			for (int a = 0; a < activitiesForForecast.length; a++ ) {
				def activity = activitiesForForecast[a]
				if (activity.activityType.isEngagement) {
					workloadForEngagements += activity.workloadEstimation
				}
				if (activity.activityType.isBillable) {
					workloadForBillable += activity.workloadEstimation
				}
				if (activity.activityType.isPaid && activity.activityType.isVacation) {
					workloadForPaidVacation += activity.workloadEstimation
				}
				if (activity.activityType.isPaid) {
					workloadForPaid += activity.workloadEstimation
				}
			}
		}
		
//		workloadForEngagements 
//		workloadForBillable
//		workloadForPaidVacation 
//		workloadForPaid 
		
		def ARVE = 0
		def URVE = 0
		
		if ((workloadForPaid + availabilityPaid - workloadForPaidVacation) != 0) {
			ARVE = (Integer)(workloadForEngagements / (workloadForPaid + availabilityPaid - workloadForPaidVacation)) * 100
		}
		
		if ((workloadForPaid + availabilityPaid - workloadForPaidVacation) != 0) {
			URVE = (Integer)(workloadForBillable / (workloadForPaid + availabilityPaid - workloadForPaidVacation)) * 100
		}
		
		System.out.println("workloadForEngagements" + workloadForEngagements)
		System.out.println("workloadForBillable" + workloadForBillable)
		System.out.println("workloadForPaidVacation" + workloadForPaidVacation)
		System.out.println("workloadForPaid" + workloadForPaid)
		
		
		def array = new Integer[52]		// week 1-52 workloads
		
		for (int a = 0; a<array.length;a++) {
			array[a] = 0;
		}
		
//		for (int a = 0; a<selectedForecastsArray.size(); a++) {
//			array[selectedForecastsArray.get(a).weekNumber-1] = 1;
//		}
		
		
		for (int d=0; d < selectedForecastsArray.size(); d++) {
			def forecast = selectedForecastsArray.get(d)
			
			int forecastStartDate = forecast.startYear * 100 + forecast.startWeek
			int forecastEndDate = forecast.endYear * 100 + forecast.endWeek
			
			Activity[] activitiesArrayForOneForecast = selectedForecastsArray[d].activities.toArray()
			int workload = 0
			for(int e = 0; e < activitiesArrayForOneForecast.length; e++) {
				workload = workload + activitiesArrayForOneForecast[e].workloadEstimation
			}
			
			for (int date = forecastStartDate; date <= forecastEndDate; date++) {
				int week = date - (Math.floor(date / 100) * 100) // Removing year from combined date
				array[week-1] = workload
	//			workloadForWeeks[pegel--] = workload
			}
		}
		
		int a = startDate - (Math.floor(startDate / 100) * 100) // Removing year from combined date
		int e = endDate - (Math.floor(endDate / 100) * 100) // Removing year from combined date
		
		List<Integer> list = new ArrayList(); // workloads
		while (a <= e){
			list.add(array[a-1])
			a++;
		}
		
		List<Integer> list2 = new ArrayList(); // availabilies
		for (int b=0; b<list.size(); b++) {
			list2.add(100-list.get(b))
		}
		
		[numberList: weekInterval, workloadList: list,  availabilityList: list2, consultant: report.consultant, reportInstance: report, arve:ARVE, urve:URVE]
		
	}


    def list(Integer max) {
        params.max = Math.min(max ?: 10, 100)
        [reportInstanceList: Report.list(params), reportInstanceTotal: Report.count()]
    }

    def create() {
		GregorianCalendar calendar = new GregorianCalendar();
		
		Report report = new Report(params)
		
		report.startWeek = calendar.get(Calendar.WEEK_OF_YEAR) + 1
		report.startYear = calendar.get(Calendar.YEAR)
		
		report.endWeek = calendar.get(Calendar.WEEK_OF_YEAR) + 1
		report.endYear = calendar.get(Calendar.YEAR)
		
        [reportInstance: report]
    }

    def save() {
        def reportInstance = new Report(params)
        if (!reportInstance.save(flush: true)) {
            render(view: "create", model: [reportInstance: reportInstance])
            return
        }

        flash.message = message(code: 'default.created.message', args: [message(code: 'report.label', default: 'Report'), reportInstance.id])
        redirect(action: "report", id: reportInstance.id)
    }

    def show(Long id) {
        def reportInstance = Report.get(id)
        if (!reportInstance) {
            flash.message = message(code: 'default.not.found.message', args: [message(code: 'report.label', default: 'Report'), id])
            redirect(action: "list")
            return
        }

        [reportInstance: reportInstance]
    }

    def edit(Long id) {
        def reportInstance = Report.get(id)
        if (!reportInstance) {
            flash.message = message(code: 'default.not.found.message', args: [message(code: 'report.label', default: 'Report'), id])
            redirect(action: "list")
            return
        }

        [reportInstance: reportInstance]
    }

    def update(Long id, Long version) {
        def reportInstance = Report.get(id)
        if (!reportInstance) {
            flash.message = message(code: 'default.not.found.message', args: [message(code: 'report.label', default: 'Report'), id])
            redirect(action: "list")
            return
        }

        if (version != null) {
            if (reportInstance.version > version) {
                reportInstance.errors.rejectValue("version", "default.optimistic.locking.failure",
                          [message(code: 'report.label', default: 'Report')] as Object[],
                          "Another user has updated this Report while you were editing")
                render(view: "edit", model: [reportInstance: reportInstance])
                return
            }
        }

        reportInstance.properties = params

        if (!reportInstance.save(flush: true)) {
            render(view: "edit", model: [reportInstance: reportInstance])
            return
        }

        flash.message = message(code: 'default.updated.message', args: [message(code: 'report.label', default: 'Report'), reportInstance.id])
        redirect(action: "show", id: reportInstance.id)
    }

    def delete(Long id) {
        def reportInstance = Report.get(id)
        if (!reportInstance) {
            flash.message = message(code: 'default.not.found.message', args: [message(code: 'report.label', default: 'Report'), id])
            redirect(action: "list")
            return
        }

        try {
            reportInstance.delete(flush: true)
            flash.message = message(code: 'default.deleted.message', args: [message(code: 'report.label', default: 'Report'), id])
            redirect(action: "list")
        }
        catch (DataIntegrityViolationException e) {
            flash.message = message(code: 'default.not.deleted.message', args: [message(code: 'report.label', default: 'Report'), id])
            redirect(action: "show", id: id)
        }
    }
}
